home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-13 / thesrc10.zip / COMMUTIL.C < prev    next >
C/C++ Source or Header  |  1992-08-12  |  68KB  |  2,143 lines

  1. /***********************************************************************/
  2. /* COMMUTIL.C -                                                        */
  3. /* This file contains all utility functions used when processing       */
  4. /* commands.                                                           */
  5. /***********************************************************************/
  6. /*
  7.  * THE - The Hessling Editor. A text editor similar to VM/CMS xedit.
  8.  * Copyright (C) 1991,1992 Mark Hessling
  9.  *
  10.  * This program is free software; you can redistribute it and/or
  11.  * modify it under the terms of the GNU General Public License as
  12.  * published by the Free Software Foundation; either version 2 of
  13.  * the License, or any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18.  * General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to:
  22.  *
  23.  *    The Free Software Foundation, Inc.
  24.  *    675 Mass Ave,
  25.  *    Cambridge, MA 02139 USA.
  26.  *
  27.  *
  28.  * If you make modifications to this software that you feel increases
  29.  * it usefulness for the rest of the community, please email the
  30.  * changes, enhancements, bug fixes as well as any and all ideas to me.
  31.  * This software is going to be maintained and enhanced as deemed
  32.  * necessary by the community.
  33.  *
  34.  * Mark Hessling                     email: M.Hessling@itc.gu.edu.au
  35.  * 36 David Road                     Phone: +61 7 849 7731
  36.  * Holland Park                      Fax:   +61 7 875 7877
  37.  * QLD 4121
  38.  * Australia
  39.  */
  40. #include <stdio.h>
  41. #include <stdlib.h>
  42.  
  43. #include "the.h"
  44. #include "key.h"
  45. #include "command.h"
  46.  
  47. /*#define DEBUG 1*/
  48.  
  49. #define NUMBER_VALID_TARGETS 32
  50. #define NUMBER_SEARCH_TARGETS 9
  51.  static SEARCH_TARGET st[NUMBER_VALID_TARGETS] =
  52.   {
  53.    {(unsigned char *)"\\",1,'\\',DIRECTION_FORWARD},
  54.    {(unsigned char *)"+\\",2,'\\',DIRECTION_FORWARD},
  55.    {(unsigned char *)"-\\",2,'\\',DIRECTION_BACKWARD},
  56.  
  57.    {(unsigned char *)"/",1,'/',DIRECTION_FORWARD},
  58.    {(unsigned char *)"+/",2,'/',DIRECTION_FORWARD},
  59.    {(unsigned char *)"-/",2,'/',DIRECTION_BACKWARD},
  60.  
  61.    {(unsigned char *)"@",1,'@',DIRECTION_FORWARD},
  62.    {(unsigned char *)"+@",2,'@',DIRECTION_FORWARD},
  63.    {(unsigned char *)"-@",2,'@',DIRECTION_BACKWARD},
  64.  
  65.    {(unsigned char *)":",1,0,0},
  66.    {(unsigned char *)"*",1,0,0},
  67.    {(unsigned char *)"-*",2,0,0},
  68.    {(unsigned char *)"0",1,0,0},
  69.    {(unsigned char *)"1",1,0,0},
  70.    {(unsigned char *)"2",1,0,0},
  71.    {(unsigned char *)"3",1,0,0},
  72.    {(unsigned char *)"4",1,0,0},
  73.    {(unsigned char *)"5",1,0,0},
  74.    {(unsigned char *)"6",1,0,0},
  75.    {(unsigned char *)"7",1,0,0},
  76.    {(unsigned char *)"8",1,0,0},
  77.    {(unsigned char *)"9",1,0,0},
  78.    {(unsigned char *)"-0",1,0,0},
  79.    {(unsigned char *)"-1",1,0,0},
  80.    {(unsigned char *)"-2",1,0,0},
  81.    {(unsigned char *)"-3",1,0,0},
  82.    {(unsigned char *)"-4",1,0,0},
  83.    {(unsigned char *)"-5",1,0,0},
  84.    {(unsigned char *)"-6",1,0,0},
  85.    {(unsigned char *)"-7",1,0,0},
  86.    {(unsigned char *)"-8",1,0,0},
  87.    {(unsigned char *)"-9",1,0,0}
  88.   };
  89.  unsigned char temp_cmd[150];
  90.  unsigned char temp_params[150];
  91.  
  92. #define MAX_CMDS 15
  93.  static unsigned char cmd[MAX_CMDS][80];
  94.  static short last_cmd=(-1),current_cmd=0,number_cmds=0,offset_cmd=0;
  95.  
  96.  bool clear_command=TRUE;
  97. /*-------------------------- external data ----------------------------*/
  98. extern LINE *next_line,*curr_line;
  99. extern VIEW_DETAILS *vd_current,*vd_first;
  100. extern char current_screen;
  101. extern SCREEN_DETAILS screen[MAX_SCREENS];        /* screen structures */
  102. extern char number_of_views;
  103. extern WINDOW *foot,*error_window;
  104. extern char error_on_screen;
  105. extern unsigned char *rec;
  106. extern unsigned short rec_len;
  107. extern unsigned char *cmd_rec;
  108. extern unsigned short cmd_rec_len;
  109. extern unsigned char in_profile;    /* indicates if processing profile */
  110. extern unsigned char file_read;  /* indicates if we have read the file */
  111. extern unsigned char *last_target;
  112. extern unsigned char curr_path[MAX_FILE_NAME+1] ;
  113. extern unsigned char sp_path[MAX_FILE_NAME+1] ;
  114. extern unsigned char sp_fname[MAX_FILE_NAME+1] ;
  115. /*---------------------- function definitions -------------------------*/
  116. #ifdef PROTO
  117. void split_command(unsigned char *,unsigned char *,unsigned char *);
  118. int param_split(unsigned char *,unsigned char *[],int );
  119. long valid_target(unsigned char *);
  120. long search_target(unsigned char *,unsigned char,long,unsigned char);
  121. short find_command(unsigned char *);
  122. unsigned char next_char(LINE *,short *);
  123. void cleanup_command_line(void);
  124. short selective_change(unsigned char *,unsigned char *,long,long,short);
  125. #else
  126. void split_command();
  127. int param_split();
  128. long valid_target();
  129. long search_target();
  130. short find_command();
  131. unsigned char next_char();
  132. void cleanup_command_line();
  133. short selective_change();
  134. #endif
  135. /***********************************************************************/
  136. #ifdef PROTO
  137. unsigned char *get_key_definition(unsigned short key)
  138. #else
  139. unsigned char *get_key_definition(key)
  140. unsigned short key;
  141. #endif
  142. /***********************************************************************/
  143. {
  144. /*--------------------------- local data ------------------------------*/
  145.  register int i;
  146.  DEFINE *curr;
  147.  bool key_defined=FALSE;
  148. /*--------------------------- processing ------------------------------*/
  149. #ifdef TRACE
  150.  trace_function("commutil.c:get_key_definition");
  151. #endif
  152. /*---------------------------------------------------------------------*/
  153. /* First determine if the key is a named key.                          */
  154. /*---------------------------------------------------------------------*/
  155.  for (i=0;i<MAX_NUMBER_KEYS && key_defined == FALSE;i++)
  156.     {
  157.      if (key == key_table[i].key_value)
  158.        {
  159.         strcpy(temp_cmd,"Key: ");
  160.         key_defined = TRUE;
  161.         strcat(temp_cmd,key_table[i].mnemonic);
  162.        }
  163.     }
  164. /*---------------------------------------------------------------------*/
  165. /* If key not defined, show it as a character and decimal. Provided it */
  166. /* is an ASCII or extended character.                                  */
  167. /*---------------------------------------------------------------------*/
  168.  if (!key_defined && key <256)
  169.     sprintf(temp_cmd,"Key: %c \\%d",(char)key,key);
  170. /*---------------------------------------------------------------------*/
  171. /* Next check to see if the key has been assigned.                     */
  172. /*---------------------------------------------------------------------*/
  173.  curr = first_define;;
  174.  while(curr != NULL)
  175.   {
  176.    if (key == curr->def_funkey && curr->def_command != (-1))
  177.      {
  178.       strcat(temp_cmd," - assigned to '");
  179.       strcat(temp_cmd,command[curr->def_command].text);
  180.       if (strcmp(curr->def_params,"") != 0)
  181.         {
  182.          strcat(temp_cmd," ");
  183.          strcat(temp_cmd,curr->def_params);
  184.         }
  185.       strcat(temp_cmd,"'");
  186. #ifdef TRACE
  187.       trace_return();
  188. #endif
  189.       return(temp_cmd);
  190.      }
  191.    curr = curr->def_next;
  192.   }
  193. /*---------------------------------------------------------------------*/
  194. /* If not, check for the default function key values.                  */
  195. /*---------------------------------------------------------------------*/
  196.  for (i=0;i<MAX_COMMANDS;i++)
  197.     {
  198.       if (key == command[i].funkey)
  199.         {
  200.          strcat(temp_cmd," - assigned to '");
  201.          strcat(temp_cmd,command[i].text);
  202.          if (strcmp(command[i].params,"") != 0)
  203.            {
  204.             strcat(temp_cmd," ");
  205.             strcat(temp_cmd,command[i].params);
  206.            }
  207.          strcat(temp_cmd,"'");
  208. #ifdef TRACE
  209.          trace_return();
  210. #endif
  211.          return(temp_cmd);
  212.         }
  213.     }
  214. /*---------------------------------------------------------------------*/
  215. /* If none of the above, it is unassigned                              */
  216. /*---------------------------------------------------------------------*/
  217.  strcat(temp_cmd," - unassigned");
  218. #ifdef TRACE
  219.  trace_return();
  220. #endif
  221.  return(temp_cmd);
  222. }
  223. /***********************************************************************/
  224. #ifdef PROTO
  225. int function_key(int key)
  226. #else
  227. int function_key(key)
  228. int key;
  229. #endif
  230. /***********************************************************************/
  231. {
  232. /*--------------------------- local data ------------------------------*/
  233.  unsigned short x,y;
  234.  register int i;
  235.  DEFINE *curr;
  236.  unsigned char cmd[81];
  237. /*--------------------------- processing ------------------------------*/
  238. #ifdef TRACE
  239.  trace_function("commutil.c:function_key");
  240. #endif
  241. /*---------------------------------------------------------------------*/
  242. /* First check to see if the function key has been redefined.          */
  243. /*---------------------------------------------------------------------*/
  244.  curr = first_define;
  245.  while(curr != NULL)
  246.   {
  247.    if (key == curr->def_funkey && curr->def_command != (-1))
  248.      {
  249.       i = (*command[curr->def_command].function)(curr->def_params);
  250. #ifdef TRACE
  251.       trace_return();
  252. #endif
  253.       return(i);
  254.      }
  255.    curr = curr->def_next;
  256.   }
  257. /*---------------------------------------------------------------------*/
  258. /* If not, check for the default function key values.                  */
  259. /*---------------------------------------------------------------------*/
  260.  for (i=0;i<MAX_COMMANDS;i++)
  261.       if (key == command[i].funkey)
  262.         {
  263.          i = (*command[i].function)(command[i].params);
  264. #ifdef TRACE
  265.          trace_return();
  266. #endif
  267.          return(i);
  268.         }
  269. #ifdef TRACE
  270.  trace_return();
  271. #endif
  272.  return(RAW_KEY);
  273. }
  274. /***********************************************************************/
  275. #ifdef PROTO
  276. bool valid_set_command(char *cmd_line)
  277. #else
  278. bool valid_set_command(cmd_line)
  279. unsigned char *cmd_line;
  280. #endif
  281. /***********************************************************************/
  282. {
  283. /*--------------------------- local data ------------------------------*/
  284.  register int i;
  285. /*--------------------------- processing ------------------------------*/
  286. #ifdef TRACE
  287.  trace_function("commutil.c:valid_set_command");
  288. #endif
  289.  for (i=0;i<MAX_COMMANDS;i++)
  290.     {
  291. /*---------------------------------------------------------------------*/
  292. /* If no command text, continue.                                       */
  293. /*---------------------------------------------------------------------*/
  294.      if (strcmp(command[i].text,"") == 0)
  295.         continue;
  296. /*---------------------------------------------------------------------*/
  297. /* Check that the supplied command matches the command for the length  */
  298. /* of the command and that the length is at least as long as the       */
  299. /* necessary significance.                                             */
  300. /*---------------------------------------------------------------------*/
  301.      if (equal(command[i].text,cmd_line,command[i].min_len)
  302.      && command[i].min_len != 0)
  303.        {
  304. #ifdef TRACE
  305.         trace_return();
  306. #endif
  307.         return(command[i].set_command);
  308.        }
  309.     }
  310. #ifdef TRACE
  311.  trace_return();
  312. #endif
  313.  return(FALSE);
  314. }
  315. /***********************************************************************/
  316. #ifdef PROTO
  317. int command_line(char *cmd_line)
  318. #else
  319. int command_line(cmd_line)
  320. unsigned char *cmd_line;
  321. #endif
  322. /***********************************************************************/
  323. {
  324. /*------------------------- external data -----------------------------*/
  325. extern LINE *first_profile_command,*current_profile_command;
  326. /*--------------------------- local data ------------------------------*/
  327.  unsigned short x,y,valid_command;
  328.  register int i;
  329.  unsigned char *cmd,*params;
  330.  int rc;
  331.  long num_lines;
  332. /*--------------------------- processing ------------------------------*/
  333. #ifdef TRACE
  334.  trace_function("commutil.c:command_line");
  335. #endif
  336. /*---------------------------------------------------------------------*/
  337. /* If the command line is blank, just return.                          */
  338. /*---------------------------------------------------------------------*/
  339.  if (strlen(cmd_line) == 0)
  340.    {
  341.     if (!in_profile)
  342.        wmove(CURRENT_WINDOW_COMMAND,0,0);
  343. #ifdef TRACE
  344.     trace_return();
  345. #endif
  346.     return(OK);
  347.    }
  348. /*---------------------------------------------------------------------*/
  349. /* If the command is to be kept displayed on the command line...       */
  350. /*---------------------------------------------------------------------*/
  351.  if (*(cmd_line) == '&')
  352.     {
  353.      clear_command = FALSE;
  354.      split_command(cmd_line+1,temp_cmd,temp_params);
  355.     }
  356.  else
  357.     {
  358.      clear_command = TRUE;
  359.      split_command(cmd_line,temp_cmd,temp_params);
  360.     }
  361.  
  362. /*---------------------------------------------------------------------*/
  363. /* Here is where we could check for synonyms first.                    */
  364. /*---------------------------------------------------------------------*/
  365.  
  366. /*---------------------------------------------------------------------*/
  367. /* Look up the command in the command array in command.h               */
  368. /*---------------------------------------------------------------------*/
  369.  valid_command = NO;
  370.  for (i=0;i<MAX_COMMANDS;i++)
  371.      {
  372. /*---------------------------------------------------------------------*/
  373. /* If no command text, continue.                                       */
  374. /*---------------------------------------------------------------------*/
  375.       if (strcmp(command[i].text,"") == 0)
  376.          continue;
  377. /*---------------------------------------------------------------------*/
  378. /* Check that the supplied command matches the command for the length  */
  379. /* of the command and that the length is at least as long as the       */
  380. /* necessary significance.                                             */
  381. /*---------------------------------------------------------------------*/
  382.       if (equal(command[i].text,temp_cmd,command[i].min_len)
  383.       && command[i].min_len != 0)
  384.          {
  385.           if (in_profile
  386.           && !command[i].valid_profile_command)
  387.             {
  388.              display_error(25,command[i].text);
  389.              cleanup_command_line();
  390. #ifdef TRACE
  391.              trace_return();
  392. #endif
  393.              return(ERROR);
  394.             }
  395.           valid_command = YES;
  396.           if (in_profile)
  397.             {
  398.              if ((command[i].set_command && file_read == NO)
  399.              || file_read == YES)
  400.                 rc = (*command[i].function)(temp_params);
  401.              else
  402.                {
  403.                 if ((current_profile_command = add_line(first_profile_command,
  404.                                                         current_profile_command,
  405.                                                         cmd_line,
  406.                                                         strlen(cmd_line))) == NULL)
  407.                   {
  408.                    display_error(30,"");
  409.                    cleanup_command_line();
  410. #ifdef TRACE
  411.                    trace_return();
  412. #endif
  413.                    return(ERROR);
  414.                   }
  415.                 if (first_profile_command == NULL)
  416.                    first_profile_command = current_profile_command;
  417.                }
  418.             }
  419.           else
  420.              rc = (*command[i].function)(temp_params);
  421.           cleanup_command_line();
  422. #ifdef TRACE
  423.           trace_return();
  424. #endif
  425.           return(rc);
  426.          }
  427.      }
  428. /*---------------------------------------------------------------------*/
  429. /* To get here, the command line does not contain a valid command...   */
  430. /* ...so, check to see if the command line is a valid target.          */
  431. /* Before we do that, if we are still in the profile file then if we   */
  432. /* actually have a potential valid target, then we have to save the    */
  433. /* command for later processsing when we have a file to search through.*/
  434. /*---------------------------------------------------------------------*/
  435.  if (in_profile && file_read == NO)
  436.    {
  437.     for (i=0;i<NUMBER_VALID_TARGETS;i++)
  438.        {
  439.         if (strncmp(temp_cmd,st[i].prefix,st[i].length) == 0)
  440.           {
  441.            if ((current_profile_command = add_line(first_profile_command,
  442.                                                current_profile_command,
  443.                                                temp_cmd,
  444.                                                strlen(temp_cmd))) == NULL)
  445.              {
  446.               display_error(30,"");
  447.               cleanup_command_line();
  448. #ifdef TRACE
  449.               trace_return();
  450. #endif
  451.               return(ERROR);
  452.              }
  453.            if (first_profile_command == NULL)
  454.               first_profile_command = current_profile_command;
  455.            cleanup_command_line();
  456. #ifdef TRACE
  457.            trace_return();
  458. #endif
  459.            return(OK);
  460.           }
  461.        }
  462.    }
  463.  num_lines = valid_target(temp_cmd);
  464.  if (num_lines == TARGET_NOT_FOUND)
  465.    {
  466.     valid_command = YES;
  467.     display_error(17,"");
  468.     cleanup_command_line();
  469. #ifdef TRACE
  470.     trace_return();
  471. #endif
  472.     return(ERROR);
  473.    }
  474.  if (num_lines != TARGET_ERROR)
  475.    {
  476.     sprintf(temp_cmd,"%-ld",num_lines);
  477.     if (in_profile && file_read == NO)
  478.       {
  479.        if ((current_profile_command = add_line(first_profile_command,
  480.                                                current_profile_command,
  481.                                                temp_cmd,
  482.                                                strlen(temp_cmd))) == NULL)
  483.          {
  484.           display_error(30,"");
  485.           cleanup_command_line();
  486. #ifdef TRACE
  487.           trace_return();
  488. #endif
  489.           return(ERROR);
  490.          }
  491.        if (first_profile_command == NULL)
  492.           first_profile_command = current_profile_command;
  493.       }
  494.     else
  495.       {
  496.        rc = Next(temp_cmd);
  497.       }
  498.     valid_command = YES;
  499.    }
  500.  
  501.  cleanup_command_line();
  502.  
  503.  if (!valid_command)
  504.     {
  505.      display_error(21,temp_cmd);
  506.      rc = OK;
  507.     }
  508.  
  509. #ifdef TRACE
  510.  trace_return();
  511. #endif
  512.  return(rc);
  513. }
  514. /***********************************************************************/
  515. #ifdef PROTO
  516. void cleanup_command_line(void)
  517. #else
  518. void cleanup_command_line()
  519. #endif
  520. /***********************************************************************/
  521. {
  522. /*--------------------------- local data ------------------------------*/
  523.  register int i;
  524. /*--------------------------- processing ------------------------------*/
  525. #ifdef TRACE
  526.  trace_function("commutil.c:cleanup_command_line");
  527. #endif
  528.  if (in_profile || number_of_views == 0)
  529.    {
  530. #ifdef TRACE
  531.     trace_return();
  532. #endif
  533.     return;
  534.    }
  535.  if (clear_command)
  536.    {
  537. /*    for (i=0;i<CURRENT_SCREEN.screen_cols-PREFIX_WIDTH;i++)
  538.         mvwaddch(CURRENT_WINDOW_COMMAND,0,i,' '); */
  539.     wmove(CURRENT_WINDOW_COMMAND,0,0);
  540.     wclrtoeol(CURRENT_WINDOW_COMMAND);
  541.     memset(cmd_rec,' ',COLS);
  542.     cmd_rec_len = 0;
  543.    }
  544.  wmove(CURRENT_WINDOW_COMMAND,0,0);
  545. #ifdef TRACE
  546.  trace_return();
  547. #endif
  548.  return;
  549. }
  550.  
  551. /***********************************************************************/
  552. #ifdef PROTO
  553. void split_command(unsigned char *cmd_line,unsigned char *cmd,
  554.                    unsigned char *params)
  555. #else
  556. void split_command(cmd_line,cmd,params)
  557. unsigned char *cmd_line;
  558. unsigned char *cmd;
  559. unsigned char *params;
  560. #endif
  561. /***********************************************************************/
  562. {
  563. /*--------------------------- local data ------------------------------*/
  564.  short pos;
  565.  unsigned char *param_ptr;
  566. /*--------------------------- processing ------------------------------*/
  567. #ifdef TRACE
  568.  trace_function("commutil.c:split_command");
  569. #endif
  570.  strcpy(cmd,cmd_line);
  571.  if ((param_ptr = (unsigned char *)strpbrk(cmd," \\/-+@")) == NULL)
  572.     {
  573.      strcpy(params,"");
  574. /*   strcpy(cmd,cmd_line); */
  575. #ifdef TRACE
  576.      trace_return();
  577. #endif
  578.      return;
  579.     }
  580.  pos = strzne(param_ptr,' ');
  581.  if (param_ptr == cmd)
  582.     {
  583.      strcpy(params,"");
  584. /*   strcpy(cmd,cmd_line); */
  585. #ifdef TRACE
  586.      trace_return();
  587. #endif
  588.      return;
  589.     }
  590.  strcpy(params,param_ptr+pos);
  591.  *(param_ptr) = '\0';
  592. /* strcpy(cmd,cmd_line);*/
  593. #ifdef TRACE
  594.  trace_return();
  595. #endif
  596.  return;
  597. }
  598. /***********************************************************************/
  599. #ifdef PROTO
  600. int param_split(unsigned char *params,unsigned char *word[],int words)
  601. #else
  602. int param_split(params,word,words)
  603. unsigned char *params;
  604. unsigned char *word[];
  605. int words;
  606. #endif
  607. /***********************************************************************/
  608. {
  609. /*--------------------------- local data ------------------------------*/
  610.  register int i;
  611.  unsigned short len;
  612.  unsigned char j,end_of_string;
  613. /*--------------------------- processing ------------------------------*/
  614. #ifdef TRACE
  615.  trace_function("commutil.c:param_split");
  616. #endif
  617.  for (i=0;i<words;i++)
  618.      word[i] = (unsigned char *)"";
  619.  j = 0;
  620.  end_of_string = YES;
  621.  len = strlen(params);
  622.  for (i=0;i<len && j<words;i++)
  623.      if (*(params+i) == ' ' || *(params+i) == '\t')
  624.         {
  625.          *(params+i) = '\0';
  626.          end_of_string = YES;
  627.         }
  628.      else
  629.         if (end_of_string == YES)
  630.            {
  631.             word[j++] = params+i;
  632.             end_of_string = NO;
  633.            }
  634.  
  635. #ifdef TRACE
  636.  trace_return();
  637. #endif
  638.  return(j);
  639. }
  640. /***********************************************************************/
  641. #ifdef PROTO
  642. long valid_target(unsigned char *target)
  643. #else
  644. long valid_target(target)
  645. unsigned char *target;
  646. #endif
  647. /***********************************************************************/
  648. /*---------------------------------------------------------------------*/
  649. /* This returns TARGET_ERROR if the target value is invalid. Otherwise */
  650. /* it returns the number of lines to the target from the 'true_line'.  */
  651. /* The 'true_line' is either the 'current_line' (if in WINDOW_COMMAND) */
  652. /* or 'focus_line' if elsewhere.                                       */
  653. /*---------------------------------------------------------------------*/
  654. {
  655. /*--------------------------- local data ------------------------------*/
  656.  long num_target;
  657.  unsigned long true_line;
  658.  register int i;
  659. /*--------------------------- processing ------------------------------*/
  660. #ifdef TRACE
  661.  trace_function("commutil.c:valid_target");
  662. #endif
  663. /*---------------------------------------------------------------------*/
  664. /* Determine 'true_line'.                                              */
  665. /*---------------------------------------------------------------------*/
  666.  if (CURRENT_VIEW->current_window == WINDOW_COMMAND
  667.  || in_profile)
  668.     true_line = CURRENT_VIEW->current_line;
  669.  else
  670.     true_line = CURRENT_VIEW->focus_line;
  671. /*---------------------------------------------------------------------*/
  672. /* Check for '*'.     This means to the end of file.                   */
  673. /*---------------------------------------------------------------------*/
  674.  if (*(target) == '*')
  675.    {
  676. #ifdef TRACE
  677.     trace_return();
  678. #endif
  679.     return(CURRENT_FILE->number_lines - true_line+1);
  680.    }
  681. /*---------------------------------------------------------------------*/
  682. /* Check for '-*'.    This means to the top of file.                   */
  683. /*---------------------------------------------------------------------*/
  684.  if (strncmp(target,"-*",2) == 0)
  685.    {
  686. #ifdef TRACE
  687.     trace_return();
  688. #endif
  689.     return(true_line*(-1));
  690.    }
  691. /*---------------------------------------------------------------------*/
  692. /* Check for search targets. These are delimited by one of '/\@' and   */
  693. /* may be positive or negative.                                        */
  694. /*---------------------------------------------------------------------*/
  695.  for (i=0;i<NUMBER_SEARCH_TARGETS;i++)
  696.     if (strncmp(target,st[i].prefix,st[i].length) == 0)
  697.       {
  698. /*---------------------------------------------------------------------*/
  699. /* Save valid target for later retrieval.                              */
  700. /*---------------------------------------------------------------------*/
  701.         if (strcmp(target+st[i].length,"") != 0)
  702.            strcpy(last_target,target);
  703.         num_target = search_target((target+st[i].length),st[i].delim,
  704.                              true_line,st[i].direction);
  705. #ifdef TRACE
  706.         trace_return();
  707. #endif
  708.         return(num_target);
  709.       }
  710. /*---------------------------------------------------------------------*/
  711. /* Check for ':' - absolute line number target.                        */
  712. /*---------------------------------------------------------------------*/
  713.  if (*(target) == ':')
  714.    {
  715.     target++;
  716.     if (!valid_integer(target))
  717.       {
  718. #ifdef TRACE
  719.        trace_return();
  720. #endif
  721.        return(TARGET_ERROR);
  722.       }
  723.     num_target = atol(target);
  724.     if (num_target < 0L)              /* invalid if negative */
  725.       {
  726. #ifdef TRACE
  727.        trace_return();
  728. #endif
  729.        return(TARGET_ERROR);
  730.       }
  731.     if (num_target >= true_line)
  732.        num_target = min((num_target - true_line),
  733.                      (CURRENT_FILE->number_lines - true_line+1));
  734.     else
  735.        num_target = (true_line - num_target)*(-1);
  736. #ifdef TRACE
  737.     trace_return();
  738. #endif
  739.     return(num_target);
  740.    }
  741. /*---------------------------------------------------------------------*/
  742. /* Lastly, check for valid integers, +ve or -ve.                       */
  743. /*---------------------------------------------------------------------*/
  744.  if (!valid_integer(target))
  745.    {
  746. #ifdef TRACE
  747.     trace_return();
  748. #endif
  749.     return(TARGET_ERROR);
  750.    }
  751.  num_target = atol(target);
  752.  if (num_target >= 0)
  753.     num_target = min(num_target,(CURRENT_FILE->number_lines - true_line+1));
  754.  else
  755.    {
  756. /*    int temp_aa;
  757.     if (true_line == 0)
  758.        temp_aa = 0;
  759.     else
  760.        temp_aa = true_line * (-1);
  761.     num_target = max((num_target),temp_aa); */
  762.     num_target = max((num_target),(true_line == 0) ? (0) : (int)(true_line*(-1)));
  763.    }
  764. #ifdef TRACE
  765.  trace_return();
  766. #endif
  767.  return(num_target);
  768. }
  769. /***********************************************************************/
  770. #ifdef PROTO
  771. long search_target(unsigned char *target,unsigned char delim,
  772.                    long true_line,unsigned char direction)
  773. #else
  774. long search_target(target,delim,true_line,direction)
  775. unsigned char *target;
  776. unsigned char delim,direction;
  777. long true_line;
  778. #endif
  779. /***********************************************************************/
  780. {
  781. /*--------------------------- local data ------------------------------*/
  782.  short start_col=0;
  783.  long rc;
  784. /*--------------------------- processing ------------------------------*/
  785. #ifdef TRACE
  786.  trace_function("commutil.c:search_target");
  787. #endif
  788.  if (*(target+strlen(target)-1) == delim)
  789.     *(target+strlen(target)-1) = '\0';
  790.  rc = find_string(true_line,&start_col,target,strlen(target),
  791.         direction,direction,CURRENT_VIEW->case_locate);
  792. #ifdef TRACE
  793.  trace_return();
  794. #endif
  795.  return(rc);
  796. }
  797. /***********************************************************************/
  798. #ifdef PROTO
  799. int get_row_for_focus_line(int cr,long fl,long cl)
  800. #else
  801. int get_row_for_focus_line(cr,fl,cl)
  802. int cr;
  803. long fl,cl;
  804. #endif
  805. /***********************************************************************/
  806. /*---------------------------------------------------------------------*/
  807. /* Returns the row within the main window where the focus line is      */
  808. /* placed. If the focus line is off the screen, or out of bounds of the*/
  809. /* current size of the file; <0 or >number_lines, this returns the     */
  810. /* current row.                                                        */
  811. /*---------------------------------------------------------------------*/
  812. {
  813. /*--------------------------- local data ------------------------------*/
  814.  register int row;
  815. /*--------------------------- processing ------------------------------*/
  816. #ifdef TRACE
  817.  trace_function("commutil.c:get_row_for_focus_line");
  818. #endif
  819.  row = (cr + (int)(fl - cl));
  820.  if (fl <= row)
  821.    {
  822. #ifdef TRACE
  823.     trace_return();
  824. #endif
  825.     return(row);
  826.    }
  827.  if (row < 0 || row > min(CURRENT_SCREEN.rows - 1,CURRENT_FILE->number_lines+1))
  828.    {
  829. #ifdef TRACE
  830.     trace_return();
  831. #endif
  832.     return(cr);
  833.    }
  834. #ifdef TRACE
  835.  trace_return();
  836. #endif
  837.  return(row);
  838. }
  839. /***********************************************************************/
  840. #ifdef PROTO
  841. int calculate_focus_line(int cr,long fl,long cl)
  842. #else
  843. int calculate_focus_line(cr,fl,cl)
  844. int cr;
  845. long fl,cl;
  846. #endif
  847. /***********************************************************************/
  848. /*---------------------------------------------------------------------*/
  849. /* Returns the new focus line. If the focus line is still in the       */
  850. /* window, it stays as is. If not,the focus   line becomes the current */
  851. /* line.                                                               */
  852. /*---------------------------------------------------------------------*/
  853. {
  854. /*--------------------------- local data ------------------------------*/
  855.  register int max_top,max_bot;
  856. /*--------------------------- processing ------------------------------*/
  857. #ifdef TRACE
  858.  trace_function("commutil.c:calculate_focus_line");
  859. #endif
  860.  max_top = max(0,cl-CURRENT_VIEW->current_row);
  861.  max_bot = min(CURRENT_FILE->number_lines+1,
  862.                cl+(CURRENT_SCREEN.rows - CURRENT_VIEW->current_row)-1);
  863.  if (fl >= max_top && fl <= max_bot)
  864.    {
  865. #ifdef TRACE
  866.     trace_return();
  867. #endif
  868.     return(fl);
  869.    }
  870. #ifdef TRACE
  871.  trace_return();
  872. #endif
  873.  return(cl);
  874. }
  875. /***********************************************************************/
  876. #ifdef PROTO
  877. void print_line(char close_spooler,long num_lines,short pagesize,
  878.                 unsigned char *text,
  879.                 unsigned char *line_term)
  880. #else
  881. void print_line(close_spooler,num_lines,pagesize,text,line_term)
  882. char close_spooler;
  883. long num_lines;
  884. short pagesize;
  885. unsigned char *text;
  886. unsigned char *line_term;
  887. #endif
  888. /***********************************************************************/
  889. {
  890. /*------------------------- external data -----------------------------*/
  891. #if !defined(DOS) && !defined(OS2)
  892.  extern unsigned char *spooler_name;
  893. #endif
  894. /*--------------------------- local data ------------------------------*/
  895. #if !defined(DOS) && !defined(OS2)
  896.  static char spooler_open=NO;
  897.  static FILE *pp;
  898. #endif
  899.  register int i;
  900.  long j;
  901.  LINE *curr;
  902.  unsigned char c;
  903.  unsigned short line_number=0;
  904. /*--------------------------- processing ------------------------------*/
  905. #ifdef TRACE
  906.  trace_function("commutil.c:print_line");
  907. #endif
  908.  if (close_spooler == YES)
  909.    {
  910. #if !defined(DOS) && !defined(OS2)
  911.     if (spooler_open == YES)
  912.        pclose(pp);
  913. #endif
  914. #ifdef TRACE
  915.     trace_return();
  916. #endif
  917.     return;
  918.    }
  919. #if !defined(DOS) && !defined(OS2)
  920.  if (spooler_open == NO)
  921.    {
  922.     pp = popen(spooler_name,"w");
  923.     spooler_open = YES;
  924.    }
  925. #endif
  926.  if (num_lines == 0L)
  927.    {
  928.     fprintf(
  929. #if !defined(DOS) && !defined(OS2)
  930.             pp,
  931. #else
  932.             stdprn,
  933. #endif
  934.             "%s%s",text,line_term);
  935. #ifdef TRACE
  936.     trace_return();
  937. #endif
  938.     return;
  939.    }
  940. /*---------------------------------------------------------------------*/
  941. /* Determine where to start writing from in the linked list.           */
  942. /*---------------------------------------------------------------------*/
  943.  /* we are actually going to print file contents */
  944.     curr = ll_find(CURRENT_FILE->first_line,CURRENT_VIEW->current_line);
  945. /*---------------------------------------------------------------------*/
  946. /* Now write out the contents of the file array to the printer.        */
  947. /*---------------------------------------------------------------------*/
  948.  for (j=0L;j<num_lines && curr->next != NULL;j++)
  949.    {
  950.     if (curr->prev != NULL)  /* not first line */
  951.       {
  952.        for (i=0;i<curr->length;i++)
  953.            fputc(*(curr->line+i),
  954. #if !defined(DOS) && !defined(OS2)
  955.               pp);
  956.        fputc('\n',pp);
  957. #else
  958.               stdprn);
  959.        fputc('\r',stdprn);
  960.        fputc('\n',stdprn);
  961. #endif
  962.        line_number++;
  963.        if (line_number == pagesize
  964.        && pagesize != 0)
  965.          {
  966. #if !defined(DOS) && !defined(OS2)
  967.           fputc('\f',pp);
  968. #else
  969.           fputc('\f',stdprn);
  970. #endif
  971.           line_number = 0;
  972.          }
  973.       }
  974.     curr = curr->next;
  975.    }
  976. #ifdef TRACE
  977.  trace_return();
  978. #endif
  979.  return;
  980. }
  981. /***********************************************************************/
  982. #ifdef PROTO
  983. unsigned char next_char(LINE *curr,short *off)
  984. #else
  985. unsigned char next_char(curr,off)
  986. LINE *curr;
  987. short *off;
  988. #endif
  989. /***********************************************************************/
  990. {
  991. /*--------------------------- local data ------------------------------*/
  992. /*--------------------------- processing ------------------------------*/
  993. #ifdef TRACE
  994.  trace_function("commutil.c:next_char");
  995. #endif
  996.  if (*(off) < curr->length)
  997.    {
  998.     (*(off))++;
  999. #ifdef TRACE
  1000.     trace_return();
  1001. #endif
  1002.     return(*(curr->line+((*(off))-1)));
  1003.    }
  1004.  *(off) = (-1);
  1005. #ifdef TRACE
  1006.  trace_return();
  1007. #endif
  1008.  return(0);
  1009. }
  1010. /***********************************************************************/
  1011. #ifdef PROTO
  1012. int add_define(unsigned char *mnemonic,unsigned char *cmd,
  1013.                unsigned char *params)
  1014. #else
  1015. int add_define(mnemonic,cmd,params)
  1016. unsigned char *mnemonic,*cmd,*params;
  1017. #endif
  1018. /***********************************************************************/
  1019. {
  1020. /*--------------------------- local data ------------------------------*/
  1021.  short key_value,cmd_nr;
  1022.  DEFINE *temp;
  1023.  register short i;
  1024. /*--------------------------- processing ------------------------------*/
  1025. #ifdef TRACE
  1026.  trace_function("commutil.c:add_define");
  1027. #endif
  1028.  if (strcmp(mnemonic,"") == 0)     /* first dummy add */
  1029.    {
  1030.     if ((first_define = (DEFINE *)memMalloc(sizeof(DEFINE),
  1031.                                    "first define")) == NULL)
  1032.       {
  1033.        display_error(30,"");
  1034. #ifdef TRACE
  1035.        trace_return();
  1036. #endif
  1037.        return(ERROR);
  1038.       }
  1039.     first_define->def_command = (-1);
  1040.     first_define->def_params = NULL;
  1041.     first_define->def_next = NULL;
  1042.     first_define->def_funkey = 0;
  1043. #ifdef TRACE
  1044.     trace_return();
  1045. #endif
  1046.     return(OK);
  1047.    }
  1048. /*---------------------------------------------------------------------*/
  1049. /* This could be cleaner. It should check to see if the combination of */
  1050. /* command and key_value are already in the list or are set in the list*/
  1051. /* of default commands.                                                */
  1052. /*---------------------------------------------------------------------*/
  1053.  
  1054. /*---------------------------------------------------------------------*/
  1055. /* Ensure that the mnemonic is upper case before we test it.           */
  1056. /*---------------------------------------------------------------------*/
  1057. /* for (i=0;i<strlen(mnemonic);i++)
  1058.     if (islower(*(mnemonic+i)))
  1059.        *(mnemonic+i) = toupper(*(mnemonic+i));
  1060.   */
  1061. /*---------------------------------------------------------------------*/
  1062. /* First check the mnemonic for decimal string value. ie begins with \ */
  1063. /*---------------------------------------------------------------------*/
  1064.  if (*(mnemonic) == '\\')
  1065.    {
  1066.     if ((key_value = atoi(mnemonic+1)) == 0)
  1067.       {
  1068.        display_error(13,mnemonic);
  1069. #ifdef TRACE
  1070.        trace_return();
  1071. #endif
  1072.        return(ERROR);
  1073.       }
  1074.    }
  1075.  else
  1076.    {
  1077.     if ((key_value = find_key_value(mnemonic)) == ERROR)
  1078.       {
  1079.        display_error(13,mnemonic);
  1080. #ifdef TRACE
  1081.        trace_return();
  1082. #endif
  1083.        return(ERROR);
  1084.        }
  1085.    }
  1086. /*---------------------------------------------------------------------*/
  1087. /* Ensure that the cmd is lower case before we test it.                */
  1088. /*---------------------------------------------------------------------*/
  1089.  for (i=0;i<strlen(cmd);i++)
  1090.     if (isupper(*(cmd+i)))
  1091.        *(cmd+i) = tolower(*(cmd+i));
  1092.  
  1093.  if ((cmd_nr = find_command(cmd)) == ERROR)
  1094.    {
  1095.     display_error(21,cmd);
  1096. #ifdef TRACE
  1097.     trace_return();
  1098. #endif
  1099.     return(ERROR);
  1100.    }
  1101. /*---------------------------------------------------------------------*/
  1102. /* Before we allocate any memory, check that combined length of cmd, a */
  1103. /* space and the parameters are less than 80.                          */
  1104. /*---------------------------------------------------------------------*/
  1105.  if (strlen(cmd)+strlen(params)+1 > 80)
  1106.    {
  1107.     display_error(37,"");
  1108. #ifdef TRACE
  1109.     trace_return();
  1110. #endif
  1111.     return(ERROR);
  1112.    }
  1113.  if ((temp = (DEFINE *)memMalloc(sizeof(DEFINE),mnemonic)) == NULL)
  1114.    {
  1115.     display_error(30,"");
  1116. #ifdef TRACE
  1117.     trace_return();
  1118. #endif
  1119.     return(ERROR);
  1120.    }
  1121.  temp->def_next = first_define->def_next;
  1122.  first_define->def_next = temp;
  1123.  temp->def_funkey = key_value;
  1124.  if ((temp->def_params = (unsigned char *)memMalloc(strlen(params)+1,params)) == NULL)
  1125.    {
  1126.     display_error(30,"");
  1127. #ifdef TRACE
  1128.     trace_return();
  1129. #endif
  1130.     return(ERROR);
  1131.    }
  1132.  strcpy(temp->def_params,params);
  1133.  temp->def_command = cmd_nr;
  1134.  
  1135. #ifdef TRACE
  1136.  trace_return();
  1137. #endif
  1138.  return(OK);
  1139. }
  1140. /***********************************************************************/
  1141. #ifdef PROTO
  1142. int find_key_value(unsigned char *mnemonic)
  1143. #else
  1144. int find_key_value(mnemonic)
  1145. unsigned char *mnemonic;
  1146. #endif
  1147. /***********************************************************************/
  1148. {
  1149. /*--------------------------- local data ------------------------------*/
  1150.  register short i;
  1151. /*--------------------------- processing ------------------------------*/
  1152. #ifdef TRACE
  1153.  trace_function("commutil.c:find_key_value");
  1154. #endif
  1155.  for (i=0;i<MAX_NUMBER_KEYS;i++)
  1156.     if (strcmp(mnemonic,key_table[i].mnemonic) == 0)
  1157.       {
  1158. #ifdef TRACE
  1159.        trace_return();
  1160. #endif
  1161.        return(key_table[i].key_value);
  1162.       }
  1163. #ifdef TRACE
  1164.  trace_return();
  1165. #endif
  1166.  return(ERROR);
  1167. }
  1168. /***********************************************************************/
  1169. #ifdef PROTO
  1170. short find_command(unsigned char *cmd)
  1171. #else
  1172. short find_command(cmd)
  1173. unsigned char *cmd;
  1174. #endif
  1175. /***********************************************************************/
  1176. {
  1177. /*--------------------------- local data ------------------------------*/
  1178.  register short i;
  1179. /*--------------------------- processing ------------------------------*/
  1180. #ifdef TRACE
  1181.  trace_function("commutil.c:find_command");
  1182. #endif
  1183.  for (i=0;i<MAX_COMMANDS;i++)
  1184.     if (strcmp(cmd,command[i].text) == 0)
  1185.       {
  1186. #ifdef TRACE
  1187.        trace_return();
  1188. #endif
  1189.        return(i);
  1190.       }
  1191. #ifdef TRACE
  1192.  trace_return();
  1193. #endif
  1194.   return(ERROR);
  1195. }
  1196. /***********************************************************************/
  1197. #ifdef PROTO
  1198. short split_change_params(char *cmd_line,char *old_str,char *new_str,char *target,
  1199.                           char *num,char *occ)
  1200. #else
  1201. short split_change_params(cmd_line,old_str,new_str,target,num,occ)
  1202. char *cmd_line,*old_str,*new_str,*target,*num,*occ;
  1203. #endif
  1204. /***********************************************************************/
  1205. {
  1206.  register short i;
  1207.  short off1,off2,off3,eos_old,eos_new,target_start;
  1208.  char cmmand_line[80],str3[20];
  1209.  
  1210.  char *cmd=cmmand_line;
  1211.  
  1212. #define SPLT_PARAMS  3
  1213.  unsigned char *word[SPLT_PARAMS];
  1214.  char parm[SPLT_PARAMS];
  1215.  unsigned short num_params;
  1216.  unsigned short x,y;
  1217.  short rc;
  1218. /*--------------------------- processing ------------------------------*/
  1219. #ifdef TRACE
  1220.  trace_function("commutil.c:split_change_params");
  1221. #endif
  1222.  
  1223.  strcpy(cmd,cmd_line);
  1224.  for (i=0;i<NUMBER_SEARCH_TARGETS;i++)
  1225.     if (*(cmd) == st[i].delim)
  1226.       break;
  1227.  if (i == NUMBER_SEARCH_TARGETS)
  1228.    {
  1229. #ifdef TRACE
  1230.     trace_return();
  1231. #endif
  1232.     return(-1);
  1233.    }
  1234. /*---------------------------------------------------------------------*/
  1235. /* Obtain the old string to change.                                    */
  1236. /*---------------------------------------------------------------------*/
  1237.  if ((off1 = strzeq(cmd+1,st[i].delim)) == (-1))
  1238.    {
  1239. #ifdef TRACE
  1240.     trace_return();
  1241. #endif
  1242.     return(-1);
  1243.    }
  1244.  eos_old = off1+1;
  1245.  *(cmd+eos_old) = '\0';
  1246.  strcpy(old_str,cmd+1);
  1247. /*---------------------------------------------------------------------*/
  1248. /* Obtain the new string to change to.                                 */
  1249. /*---------------------------------------------------------------------*/
  1250.  if ((off2 = strzeq(cmd+eos_old+1,st[i].delim)) == (-1))
  1251.    {
  1252. #ifdef TRACE
  1253.     trace_return();
  1254. #endif
  1255.     return(-1);
  1256.    }
  1257.  eos_new = eos_old+off2+1;
  1258.  *(cmd+eos_new) = '\0';
  1259.  strcpy(new_str,cmd+eos_old+1);
  1260. /*---------------------------------------------------------------------*/
  1261. /* Determine if there are any more parameters. If not, then return with*/
  1262. /* parameters of 1,1,1.                                                */
  1263. /*---------------------------------------------------------------------*/
  1264.  off1 = strzne(cmd+eos_new+1,' ');
  1265.  if (off1 == (-1))
  1266.    {
  1267.     strcpy(target,"1");
  1268.     strcpy(num,"1");
  1269.     strcpy(occ,"1");
  1270. #ifdef TRACE
  1271.     trace_return();
  1272. #endif
  1273.     return(OK);
  1274.    }
  1275.  target_start = eos_new+off1+1;
  1276.  for (i=0;i<NUMBER_SEARCH_TARGETS;i++)
  1277.     if (strncmp(cmd+target_start,st[i].prefix,st[i].length) == 0)
  1278.       break;
  1279.  if (i == NUMBER_SEARCH_TARGETS)
  1280.    {                                            /* not a string target */
  1281.     num_params = param_split(cmd+target_start,word,SPLT_PARAMS);
  1282.     if (strcmp(word[0],"") == 0)
  1283.        strcpy(target,"1");
  1284.     else
  1285.        strcpy(target,word[0]);
  1286.     if (strcmp(word[1],"") == 0)
  1287.        strcpy(num,"1");
  1288.     else
  1289.        strcpy(num,word[1]);
  1290.     if (strcmp(word[2],"") == 0)
  1291.        strcpy(occ,"1");
  1292.     else
  1293.        strcpy(occ,word[2]);
  1294. #ifdef TRACE
  1295.     trace_return();
  1296. #endif
  1297.     return(OK);
  1298.    }
  1299. /* to get here it is a valid start to a string target */
  1300.  off1 = strzeq(cmd+target_start+st[i].length,st[i].delim);
  1301.  if (off1 == (-1))
  1302.    {
  1303. #ifdef TRACE
  1304.     trace_return();
  1305. #endif
  1306.     return(-1);
  1307.    }
  1308.  off2 = off1+1+st[i].length;
  1309.  for (i=0;i<off2;i++)
  1310.      str3[i] = *(cmd+target_start+i);
  1311.  
  1312.  str3[off2] = '\0';
  1313.  strcpy(target,str3);
  1314.  num_params = param_split(cmd+target_start+off2+1,word,2);
  1315.  if (strcmp(word[0],"") == 0)
  1316.     strcpy(num,"1");
  1317.  else
  1318.     strcpy(num,word[0]);
  1319.  if (strcmp(word[1],"") == 0)
  1320.     strcpy(occ,"1");
  1321.  else
  1322.     strcpy(occ,word[1]);
  1323.  
  1324. #ifdef TRACE
  1325.  trace_return();
  1326. #endif
  1327.  return(OK);
  1328.  
  1329. }
  1330. /***********************************************************************/
  1331. #ifdef PROTO
  1332. int free_define_memory(void)
  1333. #else
  1334. int free_define_memory()
  1335. #endif
  1336. /***********************************************************************/
  1337. {
  1338. /*--------------------------- local data ------------------------------*/
  1339.  DEFINE *temp;
  1340.  unsigned char first=TRUE;
  1341. /*--------------------------- processing ------------------------------*/
  1342. #ifdef TRACE
  1343.  trace_function("commutil.c:free_define_memory");
  1344. #endif
  1345.  temp = first_define;
  1346.  while(temp != NULL)
  1347.   {
  1348.    if (!first)
  1349.       memFree(temp->def_params,temp->def_params);
  1350.    else
  1351.      first = FALSE;
  1352.    memFree(temp,"mnemonic");
  1353.    temp = temp->def_next;
  1354.   }
  1355. #ifdef TRACE
  1356.  trace_return();
  1357. #endif
  1358.  return(OK);
  1359. }
  1360. /***********************************************************************/
  1361. #ifdef PROTO
  1362. void init_command(void)
  1363. #else
  1364. void init_command()
  1365. #endif
  1366. /***********************************************************************/
  1367. {
  1368. /*--------------------------- local data ------------------------------*/
  1369.  register int i;
  1370. /*--------------------------- processing ------------------------------*/
  1371. #ifdef TRACE
  1372.  trace_function("commutil.c:init_command");
  1373. #endif
  1374.  for (i=0;i<MAX_CMDS;i++)
  1375.      strcpy(cmd[i],"");
  1376. #ifdef TRACE
  1377.  trace_return();
  1378. #endif
  1379.  return;
  1380. }
  1381. /***********************************************************************/
  1382. #ifdef PROTO
  1383. void add_command(unsigned char *new_cmd)
  1384. #else
  1385. void add_command(new_cmd)
  1386. unsigned char *new_cmd;
  1387. #endif
  1388. /***********************************************************************/
  1389. {
  1390. /*--------------------------- local data ------------------------------*/
  1391. /*--------------------------- processing ------------------------------*/
  1392. #ifdef TRACE
  1393.  trace_function("commutil.c:add_command");
  1394. #endif
  1395.  offset_cmd = 0;
  1396. /*---------------------------------------------------------------------*/
  1397. /* If the command to be added is the same as the current command or if */
  1398. /* the command line is empty, return without adding command to array.  */
  1399. /*---------------------------------------------------------------------*/
  1400.  if (strcmp(new_cmd,cmd[current_cmd]) == 0
  1401.  || strcmp(new_cmd,"") == 0)
  1402.    {
  1403. #ifdef TRACE
  1404.     trace_return();
  1405. #endif
  1406.     return;
  1407.    }
  1408.  if (number_cmds == MAX_CMDS)
  1409.     current_cmd = last_cmd = (last_cmd == MAX_CMDS-1) ? 0 : ++last_cmd;
  1410.  else
  1411.     current_cmd = ++last_cmd;
  1412.  strcpy(cmd[current_cmd],new_cmd);
  1413.  number_cmds++;
  1414.  if (number_cmds > MAX_CMDS)
  1415.     number_cmds = MAX_CMDS;
  1416. #ifdef TRACE
  1417.  trace_return();
  1418. #endif
  1419.  return;
  1420. }
  1421. /***********************************************************************/
  1422. #ifdef PROTO
  1423. unsigned char *get_command( char direction)
  1424. #else
  1425. unsigned char *get_command(direction)
  1426. char direction;
  1427. #endif
  1428. /***********************************************************************/
  1429. {
  1430. /*--------------------------- local data ------------------------------*/
  1431.  unsigned char *cmd_to_return;
  1432. /*--------------------------- processing ------------------------------*/
  1433. #ifdef TRACE
  1434.  trace_function("commutil.c:get_command");
  1435. #endif
  1436.  if (number_cmds == 0)
  1437.    {
  1438. #ifdef TRACE
  1439.     trace_return();
  1440. #endif
  1441.     return((unsigned char *)NULL);
  1442.    }
  1443.  
  1444.  if (direction == DIRECTION_BACKWARD)
  1445.    {
  1446.     if (current_cmd+1 == number_cmds)
  1447.       {
  1448.        current_cmd = 0;
  1449.        cmd_to_return = cmd[current_cmd];
  1450.       }
  1451.     else
  1452.        cmd_to_return = cmd[++current_cmd];
  1453.    }
  1454.  else
  1455.    {
  1456.     if (current_cmd+offset_cmd < 0)
  1457.       {
  1458.        current_cmd = number_cmds-1;
  1459.        cmd_to_return = cmd[current_cmd];
  1460.       }
  1461.     else
  1462.       {
  1463.        current_cmd = current_cmd+offset_cmd;
  1464.        cmd_to_return = cmd[current_cmd];
  1465.       }
  1466.    }
  1467.  offset_cmd = (-1);
  1468. #ifdef TRACE
  1469.  trace_return();
  1470. #endif
  1471.  return(cmd_to_return);
  1472. }
  1473. /***********************************************************************/
  1474. #ifdef PROTO
  1475. int execute_change_command(unsigned char *params,bool selective)
  1476. #else
  1477. int execute_change_command(params,selective)
  1478. unsigned char *params;
  1479. bool selective;
  1480. #endif
  1481. /***********************************************************************/
  1482. {
  1483. /*--------------------------- local data ------------------------------*/
  1484. #define ALT_PARAMS  4
  1485.  unsigned char *word[ALT_PARAMS];
  1486.  char parm[ALT_PARAMS];
  1487.  register int i;
  1488.  unsigned short num_params,len;
  1489.  long num_lines,long_n,long_m;
  1490.  unsigned short x,y;
  1491.  LINE *curr;
  1492.  char old_str[60],new_str[60],target[20],n[20],m[20];
  1493.  short rc,selective_rc=OK;
  1494.  char direction;
  1495.  short number_lines,number_changes,number_of_changes,number_of_occ;
  1496.  short start_col,real_start,real_end,loc;
  1497.  long true_line,last_true_line,final_target;
  1498. /*--------------------------- processing ------------------------------*/
  1499. #ifdef TRACE
  1500.  trace_function("commutil.c:execute_change_command");
  1501. #endif
  1502. /*---------------------------------------------------------------------*/
  1503. /* Validate the parameters that have been supplied. Up to 4 parameters */
  1504. /* may be supplied. The first is the string to change and its new      */
  1505. /* value, the second is the target, the third is the number of times   */
  1506. /* to change the value on one line and lastly is which occurrence to   */
  1507. /* change first.                                                       */
  1508. /*---------------------------------------------------------------------*/
  1509.  rc = split_change_params(params,old_str,new_str,target,n,m);
  1510.  if (rc == (-1))
  1511.    {
  1512.     display_error(36,"");
  1513. #ifdef TRACE
  1514.     trace_return();
  1515. #endif
  1516.     return(OK);
  1517.    }
  1518.  if ((num_lines = valid_target(target)) == TARGET_ERROR
  1519.  || CURRENT_FILE->number_lines == 0L)
  1520.     {
  1521.      display_error(17,target);
  1522. #ifdef TRACE
  1523.     trace_return();
  1524. #endif
  1525.      return(OK);
  1526.     }
  1527.  if (strcmp(n,"*") == 0)
  1528.     long_n = MAX_LONG;
  1529.  else
  1530.     if (!valid_positive_integer(n))
  1531.       {
  1532.        display_error(4,n);
  1533. #ifdef TRACE
  1534.        trace_return();
  1535. #endif
  1536.        return(OK);
  1537.       }
  1538.     else
  1539.       long_n = atol(n);
  1540.  if (!valid_positive_integer(m))
  1541.     {
  1542.      display_error(4,m);
  1543. #ifdef TRACE
  1544.      trace_return();
  1545. #endif
  1546.      return(OK);
  1547.     }
  1548.  else
  1549.    long_m = atol(m);
  1550.  if (num_lines < 0)
  1551.    direction = DIRECTION_BACKWARD;
  1552.  else
  1553.    direction = DIRECTION_FORWARD;
  1554.  
  1555. /*---------------------------------------------------------------------*/
  1556. /* If the command was issued from the command window, the current_line */
  1557. /* is the line to start changing from, otherwise it is the focus_line. */
  1558. /*---------------------------------------------------------------------*/
  1559.  if (CURRENT_VIEW->current_window == WINDOW_COMMAND)
  1560.     true_line = CURRENT_VIEW->current_line;
  1561.  else
  1562.     true_line = CURRENT_VIEW->focus_line;
  1563.  final_target = true_line+num_lines;
  1564. /*---------------------------------------------------------------------*/
  1565. /* If the true_line is on the top or bottom of file lines and we are   */
  1566. /* searching forward or backward respectively, set the true_line to be */
  1567. /* the next line in the appropriate direction.                         */
  1568. /*---------------------------------------------------------------------*/
  1569.  if (true_line == 0
  1570.  && direction == DIRECTION_FORWARD)
  1571.     true_line++;
  1572.  if (true_line == CURRENT_FILE->number_lines+1
  1573.  && direction == DIRECTION_BACKWARD)
  1574.     true_line--;
  1575.  if (true_line != CURRENT_VIEW->focus_line)
  1576.    {
  1577.     post_process_line(CURRENT_VIEW->focus_line);
  1578.     pre_process_line(true_line);
  1579.    }
  1580.  number_lines = 0;
  1581.  number_changes = 0;
  1582.  number_of_changes = 0;
  1583.  number_of_occ = 0;
  1584.  start_col = 0;
  1585.  last_true_line = true_line;
  1586.  curr = ll_find(CURRENT_FILE->first_line,true_line);
  1587.  while(1)
  1588.    {
  1589.     loc = 0;
  1590.     number_of_changes = number_of_occ = 0;
  1591.     while(loc != (-1))
  1592.       {
  1593.        real_end = min(rec_len,CURRENT_VIEW->zone_end-1);
  1594.        real_start = max(start_col,CURRENT_VIEW->zone_start-1);
  1595.  
  1596.        if (rec_len < real_start && blank_field(old_str))
  1597.          {
  1598.           loc = 0;
  1599.           rec_len = real_start;
  1600.          }
  1601.        else
  1602.          {
  1603.           if (CURRENT_VIEW->case_change == CASE_IGNORE)
  1604.              loc = memposi(rec+real_start,
  1605.                  (real_end - real_start + 1),old_str,strlen(old_str));
  1606.           else
  1607.              loc = mempos(rec+real_start,
  1608.                  (real_end - real_start + 1),old_str,strlen(old_str));
  1609.          }
  1610.        if (loc != (-1))
  1611.          {
  1612.           start_col = loc+real_start;
  1613.           if (number_of_changes <= long_n-1 && number_of_occ >= long_m-1)
  1614.             {
  1615.             /* the following block is done for change or confirm of sch */
  1616.              if (!selective)
  1617.                {
  1618.                 memdelchr(rec,start_col,rec_len,strlen(old_str));
  1619.                 rec_len -= strlen(old_str);
  1620.                 len = strlen(new_str);
  1621.                 meminsmem(rec,new_str,len,start_col,MAX_LINE_LENGTH,rec_len);
  1622.                 rec_len += len;
  1623.                 if (rec_len > MAX_LINE_LENGTH)
  1624.                   {
  1625.                    rec_len = MAX_LINE_LENGTH;
  1626.                    loc = (-1);
  1627.                   }
  1628.                 start_col += len;
  1629.                 number_changes++;
  1630.                 number_of_changes++;
  1631.                }
  1632.              else
  1633.                {
  1634.                /* selective */
  1635.                 selective_rc = selective_change(old_str,new_str,true_line,
  1636.                                                 last_true_line,start_col);
  1637.                 last_true_line = true_line;
  1638.                 switch(selective_rc)
  1639.                   {
  1640.                    case QUITOK:
  1641.                    case OK:
  1642.                         start_col += strlen(new_str);
  1643.                         number_changes++;
  1644.                         number_of_changes++;
  1645.                         if (rec_len > MAX_LINE_LENGTH)
  1646.                           {
  1647.                            rec_len = MAX_LINE_LENGTH;
  1648.                            loc = (-1);
  1649.                           }
  1650.                         break;
  1651.                    case SKIP:
  1652.                         start_col += strlen(old_str);
  1653.                         break;
  1654.                    case QUIT:
  1655.                         break;
  1656.                   }
  1657.                 if (selective_rc == QUIT || selective_rc == QUITOK)
  1658.                    break;
  1659.                }
  1660.              number_of_occ++;
  1661.             }
  1662.           else
  1663.             {
  1664.              start_col += strlen(old_str);
  1665.              number_of_occ++;
  1666.             }
  1667.           if (number_of_changes > long_n-1)
  1668. /*          ||  number_of_occ > long_n-1)*/
  1669.              loc = (-1);
  1670.          }
  1671.       } /* end while */
  1672.     if (number_of_changes != 0)       /* changes made */
  1673.       {
  1674.        post_process_line(true_line);
  1675.        number_lines++;
  1676.       }
  1677.  
  1678.     if (selective_rc == QUIT || selective_rc == QUITOK)
  1679.        break;
  1680.     true_line += direction;
  1681.     start_col = 0;
  1682.     if (direction == DIRECTION_FORWARD)
  1683.       {
  1684.        if (true_line >= final_target)
  1685.           break;
  1686.        curr = curr->next;
  1687.       }
  1688.     else
  1689.       {
  1690.        if (true_line <= final_target)
  1691.           break;
  1692.        curr = curr->prev;
  1693.       }
  1694.     pre_process_line(true_line);
  1695.  
  1696.    }
  1697. /*---------------------------------------------------------------------*/
  1698. /* If no changes were made, display error message and return.          */
  1699. /*---------------------------------------------------------------------*/
  1700.  if (number_changes == 0)
  1701.    {
  1702.     display_error(36,"");
  1703.     pre_process_line(CURRENT_VIEW->focus_line);
  1704. #ifdef TRACE
  1705.     trace_return();
  1706. #endif
  1707.     return(OK);
  1708.    }
  1709. /*---------------------------------------------------------------------*/
  1710. /* If STAY is OFF, change the current and focus lines by the number    */
  1711. /* of lines calculated from the target.                                */
  1712. /*---------------------------------------------------------------------*/
  1713.  if (!CURRENT_VIEW->stay)                                /* stay is off */
  1714.     CURRENT_VIEW->focus_line = CURRENT_VIEW->current_line += num_lines;
  1715.  
  1716.  pre_process_line(CURRENT_VIEW->focus_line);
  1717.  show_page();
  1718.  
  1719.  sprintf(old_str,"%d occurrence(s) changed on %d line(s)",number_changes,number_lines);
  1720.  display_error(0,old_str);
  1721. #ifdef TRACE
  1722.  trace_return();
  1723. #endif
  1724.  return(OK);
  1725. }
  1726. /***********************************************************************/
  1727. #ifdef PROTO
  1728. short selective_change(unsigned char *old_str,unsigned char *new_str,
  1729.                        long true_line,long last_true_line,short start_col)
  1730. #else
  1731. short selective_change(old_str,new_str,true_line,last_true_line,start_col)
  1732. unsigned char *old_str;
  1733. unsigned char *new_str;
  1734. long true_line;
  1735. long last_true_line;
  1736. short start_col;
  1737. #endif
  1738. /***********************************************************************/
  1739. {
  1740. /*--------------------------- local data ------------------------------*/
  1741.  short y,x,rc;
  1742.  long offset=true_line-last_true_line;
  1743.  unsigned short key,len;
  1744.  bool changed;
  1745. /*--------------------------- processing ------------------------------*/
  1746. #ifdef TRACE
  1747.  trace_function("commutil.c:selective_change");
  1748. #endif
  1749.  
  1750.  getyx(CURRENT_WINDOW_MAIN,y,x);
  1751.                 /* move cursor to old string a la cmatch */
  1752.                 /* display message */
  1753.                 /* accept key F5 next, F6 change, Esc? to quit */
  1754.  
  1755.  CURRENT_VIEW->focus_line = true_line;
  1756.  if (offset + y <= 0
  1757.  ||  offset + y >= CURRENT_SCREEN.rows)
  1758.    {
  1759.     CURRENT_VIEW->current_line = CURRENT_VIEW->focus_line;
  1760.     y = CURRENT_VIEW->current_row;
  1761.    }
  1762.  else
  1763.     y = get_row_for_focus_line(CURRENT_VIEW->current_row,
  1764.                                CURRENT_VIEW->focus_line,
  1765.                                CURRENT_VIEW->current_line);
  1766.  if (start_col >= CURRENT_VIEW->verify_col-1
  1767.  &&  start_col <= (CURRENT_SCREEN.cols+(CURRENT_VIEW->verify_col-1))-1)
  1768.     x = start_col-(CURRENT_VIEW->verify_col-1);
  1769.  else
  1770.    {
  1771.     x = CURRENT_SCREEN.cols / 2;
  1772.     CURRENT_VIEW->verify_col = max(1,start_col-(short)x);
  1773.     x = (start_col-(CURRENT_VIEW->verify_col-1));
  1774.    }
  1775.  
  1776.  key = 0;
  1777.  changed = FALSE;
  1778.  while(key == 0)
  1779.    {
  1780.     if (changed)
  1781.        display_error(0,"Press 'N' for next,'C' to undo 'Q' to quit");
  1782.     else
  1783.        display_error(0,"Press 'N' for next,'C' to change 'Q' to quit");
  1784.     touchwin(error_window);
  1785.     show_page();
  1786.     wnoutrefresh(CURRENT_WINDOW_MAIN);
  1787.     wmove(CURRENT_WINDOW_MAIN,y,x);
  1788.     doupdate();
  1789.     key = my_getch(CURRENT_WINDOW_MAIN);
  1790.     switch(key)
  1791.       {
  1792.        case 'N':
  1793.        case 'n':
  1794.             if (changed)
  1795.                rc = OK;
  1796.             else
  1797.                rc = SKIP;
  1798.             break;
  1799.        case 'C':
  1800.        case 'c':
  1801.             if (changed)
  1802.               {
  1803.                len = strlen(new_str);
  1804.                memdelchr(rec,start_col,rec_len,len);
  1805.                rec_len -= len;
  1806.                len = strlen(old_str);
  1807.                meminsmem(rec,old_str,len,start_col,MAX_LINE_LENGTH,rec_len);
  1808.                rec_len += len;
  1809.               }
  1810.             else
  1811.               {
  1812.                len = strlen(old_str);
  1813.                memdelchr(rec,start_col,rec_len,len);
  1814.                rec_len -= len;
  1815.                len = strlen(new_str);
  1816.                meminsmem(rec,new_str,len,start_col,MAX_LINE_LENGTH,rec_len);
  1817.                rec_len += len;
  1818.               }
  1819.             changed = (changed) ? FALSE : TRUE;
  1820.             key = 0;
  1821.             break;
  1822.        case 'Q':
  1823.        case 'q':
  1824.             if (changed)
  1825.                rc = QUITOK;
  1826.             else
  1827.                rc = QUIT;
  1828.             break;
  1829.        default:
  1830.             key = 0;
  1831.             break;
  1832.       }
  1833.    }
  1834.  
  1835.  error_on_screen = NO;
  1836.  touchwin(foot);
  1837.  wrefresh(foot);
  1838. #ifdef TRACE
  1839.  trace_return();
  1840. #endif
  1841.  return(rc);
  1842. }
  1843. /***********************************************************************/
  1844. #ifdef PROTO
  1845. int insert_new_line(unsigned char *line,int len,long num_lines,bool stay)
  1846. #else
  1847. int insert_new_line(line,len,num_lines,stay)
  1848. unsigned char *line;
  1849. int len;
  1850. long num_lines;
  1851. bool stay;
  1852. #endif
  1853. /***********************************************************************/
  1854. {
  1855. /*--------------------------- local data ------------------------------*/
  1856.  register int i;
  1857.  long true_line;
  1858.  LINE *curr,*save_curr;
  1859.  unsigned short x,y;
  1860.  bool on_bottom=FALSE;
  1861. /*--------------------------- processing ------------------------------*/
  1862. #ifdef TRACE
  1863.  trace_function("commutil.c:insert_new_line");
  1864. #endif
  1865. /*---------------------------------------------------------------------*/
  1866. /* Check from which window the command was issued and make adjustments */
  1867. /* as required.                                                        */
  1868. /* Commands issued from the command window relate to the current line, */
  1869. /* commands issued from either the prefix or main window relate to the */
  1870. /* focus line.                                                         */
  1871. /*---------------------------------------------------------------------*/
  1872.  if (CURRENT_VIEW->current_window == WINDOW_MAIN)
  1873.    {
  1874.     true_line = CURRENT_VIEW->focus_line;
  1875.    }
  1876.  if (CURRENT_VIEW->current_window == WINDOW_PREFIX)
  1877.    {
  1878.     true_line = CURRENT_VIEW->focus_line;
  1879.    }
  1880.  if (CURRENT_VIEW->current_window == WINDOW_COMMAND
  1881.  || in_profile)
  1882.    {
  1883.     true_line = CURRENT_VIEW->current_line;
  1884.    }
  1885.  post_process_line(CURRENT_VIEW->focus_line);
  1886. /*---------------------------------------------------------------------*/
  1887. /* Copy the contents of the new line into rec so it gets displayed when*/
  1888. /* show_page() is called.                                              */
  1889. /*---------------------------------------------------------------------*/
  1890. /* memcpy(rec,line,len);
  1891.  rec_len = len; */
  1892. /*---------------------------------------------------------------------*/
  1893. /* If we are on the 'Bottom of File' line reduce the true_line by 1    */
  1894. /* so that the new line is added before the bottom line.               */
  1895. /*---------------------------------------------------------------------*/
  1896.  if (true_line == CURRENT_FILE->number_lines+1)
  1897.    {
  1898.     true_line--;
  1899.     on_bottom = YES;
  1900.    }
  1901. /*---------------------------------------------------------------------*/
  1902. /* Find the current LINE pointer for the true_line.                    */
  1903. /* This is the line after which the line(s) are to be added.           */
  1904. /*---------------------------------------------------------------------*/
  1905.  curr = ll_find(CURRENT_FILE->first_line,true_line);
  1906. /*---------------------------------------------------------------------*/
  1907. /* Insert into the linked list the number of lines specified. All lines*/
  1908. /* will contain a blank line and a length of zero.                     */
  1909. /*---------------------------------------------------------------------*/
  1910.  save_curr = curr;
  1911.  for (i=0;i<num_lines;i++)
  1912.     {
  1913.      if ((curr = add_line(CURRENT_FILE->first_line,curr,line,len)) == NULL)
  1914.        {
  1915.         display_error(30,(unsigned char *)"");
  1916. #ifdef TRACE
  1917.         trace_return();
  1918. #endif
  1919.         return(ERROR);
  1920.        }
  1921.     }
  1922. /*---------------------------------------------------------------------*/
  1923. /* Fix the positioning of the marked block (if there is one and it is  */
  1924. /* in the current view).                                               */
  1925. /*---------------------------------------------------------------------*/
  1926.  adjust_marked_block(YES,true_line,num_lines);
  1927. /*---------------------------------------------------------------------*/
  1928. /* Increment the number of lines counter for the current file and the  */
  1929. /* number of alterations.                                              */
  1930. /*---------------------------------------------------------------------*/
  1931.  increment_alt();
  1932.  CURRENT_FILE->number_lines += num_lines;
  1933. /*---------------------------------------------------------------------*/
  1934. /* Sort out focus and current line.                                    */
  1935. /*---------------------------------------------------------------------*/
  1936.  CURRENT_VIEW->focus_line++;
  1937.  if (CURRENT_VIEW->current_window != WINDOW_COMMAND)
  1938.    {
  1939.     if (!in_profile)
  1940.        getyx(CURRENT_WINDOW,y,x);
  1941.     if (on_bottom)
  1942.       {
  1943.        CURRENT_VIEW->focus_line--;
  1944.        CURRENT_VIEW->current_line++;
  1945.       }
  1946.     else if (y == CURRENT_SCREEN.rows - 1)
  1947.            {
  1948.             CURRENT_VIEW->current_line++;
  1949.            }
  1950.    }
  1951.  else
  1952.     if (on_bottom)
  1953.       {
  1954.        CURRENT_VIEW->focus_line--;
  1955.        CURRENT_VIEW->current_line++;
  1956.       }
  1957. /*---------------------------------------------------------------------*/
  1958. /* If the current verify settings are not = 1, set them to there.      */
  1959. /*---------------------------------------------------------------------*/
  1960.  if (!stay)
  1961.    {
  1962.     if (CURRENT_VIEW->verify_col != 1)
  1963.        CURRENT_VIEW->verify_col = 1;
  1964.     if (CURRENT_VIEW->verify_start != 1)
  1965.        CURRENT_VIEW->verify_start = 1;
  1966.    }
  1967. /*---------------------------------------------------------------------*/
  1968. /* If we are in the main window, set up the new focus line to be       */
  1969. /* processed.                                                          */
  1970. /*---------------------------------------------------------------------*/
  1971.  if (CURRENT_VIEW->current_window != WINDOW_COMMAND)
  1972.    {
  1973.     y = get_row_for_focus_line(CURRENT_VIEW->current_row,
  1974.                                CURRENT_VIEW->focus_line,
  1975.                                CURRENT_VIEW->current_line);
  1976.     if (!stay)
  1977.       {
  1978.        i = memne(save_curr->line,' ',save_curr->length);
  1979.        if (i == (-1))
  1980.           x = 0;
  1981.        else
  1982.           x = i;
  1983.       }
  1984.     if (!in_profile)
  1985.        wmove(CURRENT_WINDOW,y,x);
  1986.    }
  1987.  pre_process_line(CURRENT_VIEW->focus_line);
  1988. /*---------------------------------------------------------------------*/
  1989. /* Re-display the main window.                                         */
  1990. /*---------------------------------------------------------------------*/
  1991.  show_page();
  1992.  
  1993. #ifdef TRACE
  1994.  trace_return();
  1995. #endif
  1996.  return(OK);
  1997. }
  1998. /***********************************************************************/
  1999. #ifdef PROTO
  2000. int parse_colours(char *attrib,chtype *pfg,chtype *pbg,chtype *pmod)
  2001. #else
  2002. int parse_colours(attrib,pfg,pbg,pmod)
  2003. char *attrib;
  2004. chtype *pfg;
  2005. chtype *pbg;
  2006. chtype *pmod;
  2007. #endif
  2008. /***********************************************************************/
  2009. {
  2010. /*--------------------------- local data ------------------------------*/
  2011.  struct attributes
  2012.  {
  2013.   unsigned char *attrib;
  2014.   short attrib_min_len;
  2015.   chtype actual_attrib;
  2016.   bool attrib_modifier;
  2017.   bool attrib_allowed_on_mono;
  2018.  };
  2019.  typedef struct attributes ATTRIBS;
  2020. #ifdef COLOR_CURSES
  2021. #define NO_ATTRIBS 13
  2022. #else
  2023. #define NO_ATTRIBS 5
  2024. #endif
  2025.  static ATTRIBS valid_attribs[NO_ATTRIBS]=
  2026.  {
  2027. #ifdef COLOR_CURSES
  2028.   {(unsigned char *)"black",3,COLOR_BLACK,FALSE,FALSE},
  2029.   {(unsigned char *)"blue",3,COLOR_BLUE,FALSE,FALSE},
  2030.   {(unsigned char *)"green",1,COLOR_GREEN,FALSE,FALSE},
  2031.   {(unsigned char *)"cyan",1,COLOR_CYAN,FALSE,FALSE},
  2032.   {(unsigned char *)"red",3,COLOR_RED,FALSE,FALSE},
  2033.   {(unsigned char *)"magenta",1,COLOR_MAGENTA,FALSE,FALSE},
  2034.   {(unsigned char *)"yellow",1,COLOR_YELLOW,FALSE,FALSE},
  2035.   {(unsigned char *)"white",1,COLOR_WHITE,FALSE,FALSE},
  2036. #endif
  2037.   {(unsigned char *)"normal",3,A_NORMAL,TRUE,TRUE},
  2038.   {(unsigned char *)"blink",3,A_BLINK,TRUE,TRUE},
  2039.   {(unsigned char *)"bold",2,A_BOLD,TRUE,TRUE},
  2040.   {(unsigned char *)"reverse",3,A_REVERSE,TRUE,TRUE},
  2041.   {(unsigned char *)"underline",1,A_UNDERLINE,TRUE,TRUE},
  2042.  };
  2043.  
  2044.  register int i;
  2045.  
  2046.  int num_colours = 0;
  2047.  chtype fg  = (chtype)0;
  2048.  chtype bg  = (chtype)0;
  2049.  chtype mod = (chtype)0;
  2050.  char *p;
  2051.  bool found;
  2052. /*--------------------------- processing ------------------------------*/
  2053. #ifdef TRACE
  2054.  trace_function("commutil.c:parse_colours");
  2055. #endif
  2056.  
  2057.  p = strtok(attrib," ");
  2058.  while(p != NULL)
  2059.    {
  2060.     found = FALSE;
  2061.     for (i=0;i<NO_ATTRIBS;i++)
  2062.        {
  2063.         if (equal(valid_attribs[i].attrib,p,valid_attribs[i].attrib_min_len))
  2064.           {
  2065.            found = TRUE;
  2066.            if (valid_attribs[i].attrib_modifier)
  2067.              {
  2068.               mod |= valid_attribs[i].actual_attrib;
  2069.               break;
  2070.              }
  2071.            else
  2072.               switch(num_colours)
  2073.                 {
  2074.                  case 0: fg = valid_attribs[i].actual_attrib;
  2075.                          num_colours++;
  2076.                          break;
  2077.                  case 1: bg = valid_attribs[i].actual_attrib;
  2078.                          num_colours++;
  2079.                          break;
  2080.                  default:display_error(1,(unsigned char *)p);
  2081. #ifdef TRACE
  2082.                          trace_return();
  2083. #endif
  2084.                          return(ERROR);
  2085.                          break;
  2086.                 }
  2087.            break;
  2088.           }
  2089.        }
  2090.     if (!found)
  2091.       {
  2092.        display_error(1,(unsigned char *)p);
  2093. #ifdef TRACE
  2094.        trace_return();
  2095. #endif
  2096.        return(ERROR);
  2097.       }
  2098.     p = strtok(NULL," ");
  2099.    }
  2100.  *pfg = fg;
  2101.  *pbg = bg;
  2102.  *pmod = mod;
  2103. #ifdef TRACE
  2104.  trace_return();
  2105. #endif
  2106.  return(OK);
  2107. }
  2108.  
  2109. /***********************************************************************/
  2110. #ifdef PROTO
  2111. void set_colour(int area,chtype fg,chtype bg,chtype mod)
  2112. #else
  2113. void set_colour(area,fg,bg,mod)
  2114. int area;
  2115. chtype fg;
  2116. chtype bg;
  2117. chtype mod;
  2118. #endif
  2119. /***********************************************************************/
  2120. {
  2121. /*--------------------------- processing ------------------------------*/
  2122. #ifdef TRACE
  2123.  trace_function("commutil.c:set_colour");
  2124. #endif
  2125.  
  2126. #ifdef COLOR_CURSES
  2127.  if (has_colors())
  2128.    {
  2129.     init_pair(area+1,fg,bg);
  2130.     colour[area] = COLOR_PAIR(area+1) | mod;
  2131.    }
  2132.  else
  2133.     colour[area] = mod;
  2134. #else
  2135.  colour[area] = mod;
  2136. #endif
  2137.  
  2138. #ifdef TRACE
  2139.  trace_return();
  2140. #endif
  2141.  return;
  2142. }
  2143.